package cz.acies.data.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.BeanProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import cz.acies.data.DBConnector;
import cz.acies.data.persist.UserLogin;
import cz.acies.data.persist.UserPerson;
import cz.acies.uniql.sql.InsertQuery;
import cz.acies.uniql.sql.SelectQuery;
import cz.acies.uniql.sql.element.UniQLCondition;
import cz.acies.utils.UIDGenerator;

public class UserLoginDAO extends DefaultDAO
{
	public static final long serialVersionUID = 6922321827705300971L;
	
	public UserLoginDAO() {
		
	}

	// -----  -----------------------------------------------------------------
	
	public static final int USER_REGISTERED_OK = 1000;
	public static final int USER_ALREADY_REGISTERED = 1100;
	public static final int USER_NAME_INCORECT = 1101;
	public static final int USER_PASSWORD_INCORECT = 1102;
	
	public UserLogin doLoad(String userName, String password) {
		UserLogin login = null;
		try {
			login = doLoad(
				new SelectQuery(dbmd())
					.addFrom("user_login")
					.add(new UniQLCondition("user_login.userName", "=", "'" + userName + "'"), "AND")
					.add(new UniQLCondition("user_login.userPassword", "=", "'" + password + "'"), "AND"));
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return login;
	}
	
	public UserLogin doLoad(UserLogin login) {
		try {
			SelectQuery sql = new SelectQuery(dbmd()).addFrom("user_login");
			if (login.getId() != null) {
				sql.add(new UniQLCondition("user_login.id", "=", "'"+login.getId()+"'"));
			} else {
				sql.add(new UniQLCondition("user_login.userName", "=", "'"+login.getUserName()+"'"), "AND")
				   .add(new UniQLCondition("user_login.userPassword", "=", "'"+login.getUserPassword()+"'"));
			}
			login = doLoad(sql);
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return login;
	}
	
	private UserLogin doLoad(SelectQuery sql) throws Exception {
		UserLogin login = qr().query(sql.toSQLString(), 
			new BeanHandler<UserLogin>(UserLogin.class, 
				new BasicRowProcessor(new BeanProcessor() {
					@Override
					public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {
						T obj = super.toBean(rs, type);
						if (obj instanceof UserLogin) {
							UserLogin login = (UserLogin)obj;
							login.setId(rs.getString("id"));
							login.setPerson(new UserPerson(rs.getString("personId")));
						}
						return obj;
					}
				}) 
			)
		);
		return login;
	}
	
	public int doAppend(UserLogin login) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			String userName = login.getUserName();
			String password = login.getUserPassword();
			if (userName == null || userName.trim().length() == 0) return USER_NAME_INCORECT;
			if (!passwordVerify(password)) {
				return USER_PASSWORD_INCORECT;
			}
			
			//String query = "SELECT * FROM user_login WHERE user_login.USER_NAME = '"+login.getUserName()+"'";
			
			conn = DBConnector.instance().conn();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(new SelectQuery(dbmd())
				.addFrom("user_login")
				.add(new UniQLCondition("user_login.userName", "=", "'"+login.getUserName()+"'"))
				.toSQLString());
			if (rs.first()) {
				return USER_ALREADY_REGISTERED;
			} else {
				String personId = null; 
				String id = UIDGenerator.createUID("WX.L.");
				if (login.getPerson() != null) {
					personId = login.getPerson().getId(); 
				} else {
					personId = UIDGenerator.createUID("WX.R.");
				}
				//UserPerson person = new UserPerson(personId);
				stmt.executeUpdate(new InsertQuery(dbmd())
					.into("user_login")
					.addParam("id", ""+id)
					.addParam("userName", ""+userName)
					.addParam("userPassword", ""+password)
					.addParam("personId", ""+personId)
					.toSQLString());
			}
		} catch (Exception exc) {
			exc.printStackTrace();
		} finally {
			try { if (rs != null) rs.close(); } catch (Exception e) {}
			try { if (stmt != null) stmt.close(); } catch (Exception e) {}
			try { if (conn != null) conn.close(); } catch (Exception e) {}
		} 
		return USER_REGISTERED_OK;
	}
	
	private String PASSWORD_PATTERN = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%_\\.]).{6,20})";
	
	private boolean passwordVerify(String password) { 
		if (password == null || password.length() == 0) { return false; }
		return password.matches(PASSWORD_PATTERN);
	}
	
	// -----  -----------------------------------------------------------------
	/*
	private QueryRunner qr = null;
	
	protected QueryRunner qr() {
		return qr = new QueryRunner(ds()); 
	}
	*/
}
